
//package java_cup;

/**
 * This class represents the complete "actionPart" table of the CUPParser. It has one
 * row for each state in the parse machine, and a column for each terminal
 * SymbolDraft. Each entry in the table represents a Shift, reduce, or an error.
 *
 * @see java_cup.parse_action
 * @see java_cup.parse_action_row
 * @version last updated: 11/25/95
 * @author Scott Hudson
 */
public class ParseActionTable {

    /*-----------------------------------------------------------*/
    /*--- Constructor(s) ----------------------------------------*/
    /*-----------------------------------------------------------*/

    /**
     * Simple constructor. AllVns terminals, non-terminals, and AllProdctions must
     * already have been entered, and the viable prefix recognizer should have been
     * constructed before this is called.
     */
    public ParseActionTable() {
        /* determine how many states we are working with */
        _stateCount = LALRState.Count;

        /* allocate the array and fill it in with empty rows */
        under_state = new ParseActionRow[_stateCount];
        for (int i = 0; i < _stateCount; i++)
            under_state[i] = new ParseActionRow();
    }

    /*-----------------------------------------------------------*/
    /*--- (Access to) Instance Variables ------------------------*/
    /*-----------------------------------------------------------*/

    /** How many rows/states are in the machine/table. */
    public int _stateCount;

    /** How many rows/states are in the machine/table. */
    public int StateCount => _stateCount;

    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

    /** Actual array of rows, one per state. */
    public ParseActionRow[] under_state;

    /*-----------------------------------------------------------*/
    /*--- General Methods ---------------------------------------*/
    /*-----------------------------------------------------------*/

    /**
     * Check the table to ensure that AllVns AllProdctions have been reduced. Issue a
     * warning message (to System.err) for each production that is never reduced.
     */
    public void checkReductions() /*throws internal_error*/ {
        ParseAction act;

        /* tabulate reductions -- look at every table entry */
        for (int row = 0; row < StateCount; row++) {
            for (int col = 0; col < ParseActionRow.Count; col++) {
                /* look at the actionPart entry to see if its a reduce */
                act = under_state[row].parseActions[col];
                if (act != null && act.Kind == ParseAction.REDUCE) {
                    /* tell production that we used it */
                    ((ReduceAction)act).                    /* tell production that we used it */
                    ReduceWith.IncreaseReductionUse();
                }
            }
        }

        /* now go across every production and make sure we hit it */
        foreach (var prod in ProductionDraft.AllProductions()) {
            /* if we didn't hit it give a warning */
            if (prod.numReductions == 0) {
                /*
                 * count it * emit.not_reduced++;
                 * 
                 * /* give a warning if they haven't been turned off
                 */
                if (!Emit.nowarn) {

                    //ErrorManager.getManager().emit_warning("*** Production \"" + prod.to_simple_string() + "\" never reduced");
                }
            }
        }
    }

    /*
     * . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*
     * 
     * /** Convert to a string.
     */
    /*@Override*/
    public override string ToString() {
        String result;
        int cnt;

        result = "-------- ACTION_TABLE --------\n";
        for (int row = 0; row < StateCount; row++) {
            result += "From state #" + row + "\n";
            cnt = 0;
            for (int col = 0; col < ParseActionRow.Count; col++) {
                /* if the actionPart is not an error print it */
                if (under_state[row].parseActions[col].Kind != ParseAction.ERROR) {
                    result += " [term " + col + ":" + under_state[row].parseActions[col] + "]";

                    /* end the line after the 2nd one */
                    cnt++;
                    if (cnt == 2) {
                        result += "\n";
                        cnt = 0;
                    }
                }
            }
            /* finish the line if we haven't just done that */
            if (cnt != 0)
                result += "\n";
        }
        result += "------------------------------";

        return result;
    }

    /*-----------------------------------------------------------*/

}
